home *** CD-ROM | disk | FTP | other *** search
/ 3D Games (Spidla) / 3dhry2.iso / Tank Wars 3D / src / OPENGL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2003-03-17  |  16.5 KB  |  517 lines

  1. #include <stdio.h>
  2. #include <dinput.h>
  3.  
  4. #include "tankwars.h"
  5.  
  6. // Direct Input
  7. LPDIRECTINPUT7            g_DI;
  8. // Keyboard Device
  9. LPDIRECTINPUTDEVICE7    g_KDIDev;
  10.  
  11. HDC    hDC=NULL;            // Private GDI Device Context
  12. HGLRC hRC=NULL;            // Permanent Rendering Context
  13. HWND hWnd=NULL;            // Holds Our Window Handle
  14. HINSTANCE hInstance;    // Holds The Instance Of The Application
  15.  
  16. BYTE key[256];            // Array Used For The Keyboard Routine
  17. bool mousebutton[2];    // Mouse buttons
  18. bool active=TRUE;        // Window Active Flag Set To TRUE By Default
  19. bool fullscreen=TRUE;    // Fullscreen Flag Set To Fullscreen Mode By Default
  20.  
  21. extern int screen_h;
  22. extern int screen_w;
  23.  
  24. GLuint    base;            // Base Display List For The Font
  25. GLuint    texture[TOTAL_TEXTURES];
  26.  
  27. // Declaration For WndProc:
  28. LRESULT    CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  29.  
  30. int gamestart(void);
  31. int InitGL(GLvoid);
  32.  
  33. // Loads A Bitmap Image:
  34. AUX_RGBImageRec *LoadBMP(char *Filename)
  35. {
  36.     FILE *File=NULL;
  37.     // Make Sure A Filename Was Given:
  38.     if (!Filename)
  39.         return NULL;
  40.     File=fopen(Filename,"r");
  41.     
  42.     // Does The File Exist?
  43.     if (File)
  44.     {
  45.         // Close The Handle:
  46.         fclose(File);
  47.         // Load The Bitmap And Return A Pointer:
  48.         return auxDIBImageLoad(Filename);
  49.     }
  50.     // If Load Failed Return NULL:
  51.     return NULL;
  52. }
  53.  
  54. // Build Our Font Display List:
  55. GLvoid BuildFont(GLvoid)
  56. {
  57.     int loop;
  58.  
  59.     float    cx;
  60.     float    cy;
  61.     
  62.     // Creating 256 Display Lists:
  63.     base=glGenLists(256);
  64.     
  65.     // Select Our Font Texture:
  66.     glBindTexture(GL_TEXTURE_2D, texture[FONT_TEXTURE]);
  67.     for (loop=0; loop<256; loop++)
  68.     {
  69.         cx=float(loop%16)/16.0f;
  70.         cy=float(loop/16)/16.0f;
  71.         // Start Building A List:
  72.         glNewList(base+loop,GL_COMPILE);
  73.             glBegin(GL_QUADS);                    // Use A Quad For Each Character
  74.                 glTexCoord2f(cx,1-cy-0.0625f);            // Texture Coord (Bottom Left)
  75.                 glVertex2i(0,0);                // Vertex Coord (Bottom Left)
  76.                 glTexCoord2f(cx+0.0625f,1-cy-0.0625f);        // Texture Coord (Bottom Right)
  77.                 glVertex2i(16,0);                // Vertex Coord (Bottom Right)
  78.                 glTexCoord2f(cx+0.0625f,1-cy);            // Texture Coord (Top Right)
  79.                 glVertex2i(16,16);                // Vertex Coord (Top Right)
  80.                 glTexCoord2f(cx,1-cy);                // Texture Coord (Top Left)
  81.                 glVertex2i(0,16);                // Vertex Coord (Top Left)
  82.             glEnd();                        // Done Building Our Quad (Character)
  83.             glTranslated(10,0,0);                    // Move To The Right Of The Character
  84.         glEndList();                            // Done Building The Display List
  85.     }                                    // Loop Until All 256 Are Built
  86. }
  87.  
  88. GLvoid KillFont(GLvoid)                                // Delete The Font From Memory
  89. {
  90.     glDeleteLists(base,256);                        // Delete All 256 Display Lists
  91. }
  92.  
  93. // Where The Printing Happens:
  94. GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...)
  95. {
  96.     char string[256];
  97.     va_list        ap;                    // Pointer To List Of Arguments
  98.     va_start(ap, fmt);                    // Parses The String For Variables
  99.         vsprintf(string, fmt, ap);                // And Converts Symbols To Actual Numbers
  100.     va_end(ap);                        // Results Are Stored In Text
  101.  
  102.  
  103.     if (set>1)                                // Is set Greater Than One?
  104.         set=1;                                // If So, Make Set Equal One
  105.     glEnable(GL_BLEND);
  106.     glBindTexture(GL_TEXTURE_2D, texture[FONT_TEXTURE]);    // Select Our Font Texture
  107.     glDisable(GL_DEPTH_TEST);                        // Disables Depth Testing
  108.     glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
  109.     glPushMatrix();                                // Store The Projection Matrix
  110.     glLoadIdentity();                            // Reset The Projection Matrix
  111.     glOrtho(0,640,0,480,-1,1);                            // Set Up An Ortho Screen
  112.     glMatrixMode(GL_MODELVIEW);                        // Select The Modelview Matrix
  113.     glPushMatrix();                                // Store The Modelview Matrix
  114.     glLoadIdentity();                            // Reset The Modelview Matrix
  115.     glTranslated(x,y,0);                            // Position The Text (0,0 - Bottom Left)
  116.     glListBase(base-32+(128*set));                        // Choose The Font Set (0 or 1)
  117.     glCallLists(strlen(string),GL_BYTE,string);                // Write The Text To The Screen
  118.     glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
  119.     glPopMatrix();                                // Restore The Old Projection Matrix
  120.     glMatrixMode(GL_MODELVIEW);                        // Select The Modelview Matrix
  121.     glPopMatrix();                                // Restore The Old Projection Matrix
  122.     glEnable(GL_DEPTH_TEST);                        // Enables Depth Testing
  123.     glDisable(GL_BLEND);
  124. }
  125.  
  126.  
  127.  
  128. // This function resizes and initialize the GL window
  129. GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
  130. {
  131.     // Prevent A Divide By Zero By:
  132.     if (height==0)
  133.         height=1;
  134.     
  135.     // Reset The Current Viewport:
  136.     glViewport(0,0,width,height);
  137.  
  138.     // Select The Projection Matrix:
  139.     glMatrixMode(GL_PROJECTION);
  140.     // Reset The Projection Matrix:
  141.     glLoadIdentity();
  142.  
  143.     // Calculate The Aspect Ratio Of The Window:
  144.     gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,260.0f,430.0f);
  145.  
  146.     // Select The Modelview Matrix:
  147.     glMatrixMode(GL_MODELVIEW);
  148.     // Reset The Modelview Matrix:
  149.     glLoadIdentity();
  150. }
  151.  
  152. // This function Properly Kills The Window:
  153. GLvoid KillGLWindow(GLvoid)
  154. {
  155.     // Are We In Fullscreen Mode?
  156.     if (fullscreen)
  157.     {
  158.         // Switch Back To The Desktop:
  159.         ChangeDisplaySettings(NULL,0);
  160.         // Show Mouse Pointer
  161.         ShowCursor(TRUE);
  162.     }
  163.  
  164.     // Do We Have A Rendering Context?
  165.     if (hRC)
  166.     {
  167.         // Are We Able To Release The DC And RC Contexts?
  168.         if (!wglMakeCurrent(NULL,NULL))
  169.             MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  170.  
  171.         // Are We Able To Delete The RC?
  172.         if (!wglDeleteContext(hRC))
  173.             MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  174.         
  175.         hRC=NULL;
  176.     }
  177.  
  178.     // Are We Able To Release The DC?
  179.     if (hDC && !ReleaseDC(hWnd,hDC))
  180.     {
  181.         MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  182.         hDC=NULL;
  183.     }
  184.  
  185.     // Are We Able To Destroy The Window?
  186.     if (hWnd && !DestroyWindow(hWnd))
  187.     {
  188.         MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  189.         hWnd=NULL;
  190.     }
  191.  
  192.     // Are We Able To Unregister Class?
  193.     if (!UnregisterClass("OpenGL",hInstance))
  194.     {
  195.         MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  196.         hInstance=NULL;
  197.     }
  198.     // Destroy The Font:
  199.     KillFont();
  200. }
  201.  
  202. // This Code Creates Our OpenGL Window.  Parameters Are:
  203. // title            - Title To Appear At The Top Of The Window
  204. // width            - Width Of The GL Window Or Fullscreen Mode
  205. // height            - Height Of The GL Window Or Fullscreen Mode
  206. // bits            - Number Of Bits To Use For Color (8/16/24/32)
  207. // fullscreenflag    - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)
  208.  BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
  209. {
  210.     GLuint        PixelFormat;            // Holds The Results After Searching For A Match
  211.     WNDCLASS    wc;                        // Windows Class Structure
  212.     DWORD        dwExStyle;                // Window Extended Style
  213.     DWORD        dwStyle;                // Window Style
  214.     RECT        WindowRect;                // Grabs Rectangle Upper Left / Lower Right Values
  215.     WindowRect.left=(long)0;            // Set Left Value To 0
  216.     WindowRect.right=(long)width;        // Set Right Value To Requested Width
  217.     WindowRect.top=(long)0;                // Set Top Value To 0
  218.     WindowRect.bottom=(long)height;        // Set Bottom Value To Requested Height
  219.  
  220.     fullscreen=fullscreenflag;            // Set The Global Fullscreen Flag
  221.  
  222.     hInstance            = GetModuleHandle(NULL);                // Grab An Instance For Our Window
  223.     wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    // Redraw On Size, And Own DC For Window.
  224.     wc.lpfnWndProc        = (WNDPROC) WndProc;                    // WndProc Handles Messages
  225.     wc.cbClsExtra        = 0;                                    // No Extra Window Data
  226.     wc.cbWndExtra        = 0;                                    // No Extra Window Data
  227.     wc.hInstance        = hInstance;                            // Set The Instance
  228.     wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);            // Load The Default Icon
  229.     wc.hCursor            = LoadCursor(NULL, IDC_ARROW);            // Load The Arrow Pointer
  230.     wc.hbrBackground    = NULL;                                    // No Background Required For GL
  231.     wc.lpszMenuName        = NULL;                                    // We Don't Want A Menu
  232.     wc.lpszClassName    = "OpenGL";                                // Set The Class Name
  233.  
  234.     if (!RegisterClass(&wc))                                    // Attempt To Register The Window Class
  235.     {
  236.         MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  237.         return FALSE;
  238.     }
  239.     
  240.     // Attempt Fullscreen Mode?
  241.     if (fullscreen)
  242.     {
  243.         DEVMODE dmScreenSettings;                                // Device Mode
  244.         memset(&dmScreenSettings,0,sizeof(dmScreenSettings));    // Makes Sure Memory's Cleared
  245.         dmScreenSettings.dmSize=sizeof(dmScreenSettings);        // Size Of The Devmode Structure
  246.         dmScreenSettings.dmPelsWidth    = width;                // Selected Screen Width
  247.         dmScreenSettings.dmPelsHeight    = height;                // Selected Screen Height
  248.         dmScreenSettings.dmBitsPerPel    = bits;                    // Selected Bits Per Pixel
  249.         dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
  250.  
  251.         // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
  252.         if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
  253.         {
  254.             // If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.
  255.             if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
  256.             {
  257.                 fullscreen=FALSE;        // Windowed Mode Selected.
  258.             }
  259.             else
  260.             {
  261.                 // Pop Up A Message Box Letting User Know The Program Is Closing.
  262.                 MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
  263.                 return FALSE;
  264.             }
  265.         }
  266.     }
  267.  
  268.     // Are We Still In Fullscreen Mode?
  269.     if (fullscreen)
  270.     {
  271.         dwExStyle=WS_EX_APPWINDOW;                                // Window Extended Style
  272.         dwStyle=WS_POPUP;                                        // Windows Style
  273.         ShowCursor(FALSE);                                        // Hide Mouse Pointer
  274.     }
  275.     else
  276.     {
  277.         dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;            // Window Extended Style
  278.         dwStyle=WS_OVERLAPPEDWINDOW;                            // Windows Style
  279.     }
  280.  
  281.     // Adjust Window To True Requested Size:
  282.     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
  283.  
  284.     // Create The Window
  285.     if (!(hWnd=CreateWindowEx(    dwExStyle,                            // Extended Style For The Window
  286.                                 "OpenGL",                            // Class Name
  287.                                 title,                                // Window Title
  288.                                 dwStyle |                            // Defined Window Style
  289.                                 WS_CLIPSIBLINGS |                    // Required Window Style
  290.                                 WS_CLIPCHILDREN,                    // Required Window Style
  291.                                 0, 0,                                // Window Position
  292.                                 WindowRect.right-WindowRect.left,    // Calculate Window Width
  293.                                 WindowRect.bottom-WindowRect.top,    // Calculate Window Height
  294.                                 NULL,                                // No Parent Window
  295.                                 NULL,                                // No Menu
  296.                                 hInstance,                            // Instance
  297.                                 NULL)))                                // Dont Pass Anything To WM_CREATE
  298.     {
  299.         // Reset The Display:
  300.         KillGLWindow();
  301.         MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  302.         return FALSE;
  303.     }
  304.  
  305.     static    PIXELFORMATDESCRIPTOR pfd=                // pfd Tells Windows How We Want Things To Be
  306.     {
  307.         sizeof(PIXELFORMATDESCRIPTOR),                // Size Of This Pixel Format Descriptor
  308.         1,                                            // Version Number
  309.         PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
  310.         PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
  311.         PFD_DOUBLEBUFFER,                            // Must Support Double Buffering
  312.         PFD_TYPE_RGBA,                                // Request An RGBA Format
  313.         bits,                                        // Select Our Color Depth
  314.         0, 0, 0, 0, 0, 0,                            // Color Bits Ignored
  315.         0,                                            // No Alpha Buffer
  316.         0,                                            // Shift Bit Ignored
  317.         0,                                            // No Accumulation Buffer
  318.         0, 0, 0, 0,                                    // Accumulation Bits Ignored
  319.         16,                                            // 16Bit Z-Buffer (Depth Buffer)  
  320.         0,                                            // No Stencil Buffer
  321.         0,                                            // No Auxiliary Buffer
  322.         PFD_MAIN_PLANE,                                // Main Drawing Layer
  323.         0,                                            // Reserved
  324.         0, 0, 0                                        // Layer Masks Ignored
  325.     };
  326.     
  327.     if (!(hDC=GetDC(hWnd)))                            // Did We Get A Device Context?
  328.     {
  329.         KillGLWindow();                                // Reset The Display
  330.         MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  331.         return FALSE;
  332.     }
  333.  
  334.     if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))    // Did Windows Find A Matching Pixel Format?
  335.     {
  336.         KillGLWindow();                                // Reset The Display
  337.         MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  338.         return FALSE;
  339.     }
  340.  
  341.     if(!SetPixelFormat(hDC,PixelFormat,&pfd))        // Are We Able To Set The Pixel Format?
  342.     {
  343.         KillGLWindow();                                // Reset The Display
  344.         MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  345.         return FALSE;
  346.     }
  347.  
  348.     if (!(hRC=wglCreateContext(hDC)))                // Are We Able To Get A Rendering Context?
  349.     {
  350.         KillGLWindow();                                // Reset The Display
  351.         MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  352.         return FALSE;
  353.     }
  354.  
  355.     if(!wglMakeCurrent(hDC,hRC))                    // Try To Activate The Rendering Context
  356.     {
  357.         KillGLWindow();                                // Reset The Display
  358.         MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  359.         return FALSE;
  360.     }
  361.  
  362.     ShowWindow(hWnd,SW_SHOW);                        // Show The Window
  363.     SetForegroundWindow(hWnd);                        // Slightly Higher Priority
  364.     SetFocus(hWnd);                                    // Sets Keyboard Focus To The Window
  365.     ReSizeGLScene(width, height);                    // Set Up Our Perspective GL Screen
  366.  
  367.     if (!InitGL())                                    // Initialize Our Newly Created GL Window
  368.     {
  369.         KillGLWindow();                                // Reset The Display
  370.         MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  371.         return FALSE;
  372.     }
  373.  
  374.     return TRUE;
  375. }
  376.  
  377. // Initializes Direct Input ( Add )
  378. int DI_Init()
  379. {
  380.     // Create Direct Input
  381.     if ( DirectInputCreateEx(    hInstance,            // Window Instance
  382.                     DIRECTINPUT_VERSION,        // Direct Input Version
  383.                     IID_IDirectInput7,        // Version 7
  384.                     (void**)&g_DI,            // Direct Input
  385.                     NULL ) )            // NULL Parameter
  386.     {
  387.         return(false);                        // Couldn't Initialize Direct Input
  388.     }
  389.  
  390.     // Create The Keyboard Device
  391.     if ( g_DI->CreateDeviceEx(    GUID_SysKeyboard,        // Define Which Device Tto Create (KeyBoard,Mouse,or Joystick)
  392.                     IID_IDirectInputDevice7,    // Version 7
  393.                     (void**)&g_KDIDev,        // KeyBoard Device
  394.                     NULL ) )            // NULL Parameter
  395.     {
  396.         return(false);                        // Couldn't Create The Keyboard Device
  397.     }
  398.  
  399.     // Set The Keyboard Data Format
  400.     if ( g_KDIDev->SetDataFormat(&c_dfDIKeyboard) )
  401.     {
  402.         return(false);                        // Could Not Set The Data Format
  403.     }
  404.  
  405.     // Set The Cooperative Level
  406.     if ( g_KDIDev->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE) )
  407.     {
  408.         return(false);                        // Could Not Set The Cooperative Level
  409.     }
  410.  
  411.     if (g_KDIDev)                            // Did We Create The Keyboard Device?
  412.         g_KDIDev->Acquire();                    // If So, Acquire It
  413.     else                                // If Not
  414.         return(false);                        // Return False
  415.  
  416.     return(true);                            // Everything Ok, Return True
  417. }
  418.  
  419. // Destroys DX ( Add )
  420. void DX_End()
  421. {
  422.     if (g_DI)
  423.     {
  424.         if (g_KDIDev)
  425.         {
  426.             g_KDIDev->Unacquire();
  427.             g_KDIDev->Release();
  428.             g_KDIDev = NULL;
  429.         }
  430.  
  431.         g_DI->Release();
  432.         g_DI = NULL;
  433.     }
  434. }
  435.  
  436.  
  437. LRESULT CALLBACK WndProc(    HWND    hWnd,            // Handle For This Window
  438.                             UINT    uMsg,            // Message For This Window
  439.                             WPARAM    wParam,            // Additional Message Information
  440.                             LPARAM    lParam)            // Additional Message Information
  441. {
  442.     switch (uMsg)                                    // Check For Windows Messages
  443.     {
  444.         case WM_ACTIVATE:                            // Watch For Window Activate Message
  445.         {
  446.             if (!HIWORD(wParam))                    // Check Minimization State
  447.             {
  448.                 active=TRUE;                        // Program Is Active
  449.             }
  450.             else
  451.             {
  452.                 active=FALSE;                        // Program Is No Longer Active
  453.             }
  454.  
  455.             return 0;                                // Return To The Message Loop
  456.         }
  457.  
  458.         case WM_SYSCOMMAND:                            // Intercept System Commands
  459.         {
  460.             switch (wParam)                            // Check System Calls
  461.             {
  462.                 case SC_SCREENSAVE:                    // Screensaver Trying To Start?
  463.                 case SC_MONITORPOWER:                // Monitor Trying To Enter Powersave?
  464.                 return 0;                            // Prevent From Happening
  465.             }
  466.             break;                                    // Exit
  467.         }
  468.  
  469.         case WM_CLOSE:                                // Did We Receive A Close Message?
  470.         {
  471.             PostQuitMessage(0);                        // Send A Quit Message
  472.             return 0;                                // Jump Back
  473.         }
  474.  
  475. /*
  476.         case WM_KEYDOWN:                            // Is A Key Being Held Down?
  477.         {
  478.             key[wParam] = TRUE;                        // If So, Mark It As TRUE
  479.             return 0;                                // Jump Back
  480.         }
  481.  
  482.         case WM_KEYUP:                                // Has A Key Been Released?
  483.         {
  484.             key[wParam] = FALSE;                    // If So, Mark It As FALSE
  485.             return 0;                                // Jump Back
  486.         }
  487. */
  488.         case WM_LBUTTONDOWN:
  489.         {
  490.             mousebutton[0]=1;
  491.             return 0;
  492.         }
  493.         case WM_LBUTTONUP:
  494.         {
  495.             mousebutton[0]=0;
  496.             return 0;
  497.         }
  498.  
  499.         case WM_SIZE:                                // Resize The OpenGL Window
  500.         {
  501.             ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Height
  502.             return 0;                                // Jump Back
  503.         }
  504.     }
  505.  
  506.     // Pass All Unhandled Messages To DefWindowProc
  507.     return DefWindowProc(hWnd,uMsg,wParam,lParam);
  508. }
  509.  
  510. int WINAPI WinMain(    HINSTANCE    hInstance,            // Instance
  511.                     HINSTANCE    hPrevInstance,        // Previous Instance
  512.                     LPSTR        lpCmdLine,            // Command Line Parameters
  513.                     int            nCmdShow)            // Window Show State
  514. {
  515.     return gamestart();
  516. }
  517.